home *** CD-ROM | disk | FTP | other *** search
/ FishMarket 1.0 / FishMarket v1.0.iso / fishies / 351-375 / disk_360 / uucp / uucp0.lzh / src / anews / unpackmail.c < prev    next >
C/C++ Source or Header  |  1990-05-17  |  6KB  |  264 lines

  1.  
  2. /*
  3.  *  UNPACKMAIL.C
  4.  */
  5.  
  6. #include "news.h"
  7. #include <expand_path.h>
  8. #include <ctype.h>
  9.  
  10. static FILE *mp;
  11.  
  12. static void
  13. CloseOldFile(void)
  14. {
  15.     if (mp) {
  16.     fflush(mp);
  17.     if (fclose(mp) != 0) {
  18.         printf("FATAL -- I/O error while writing message\n");
  19.         exit(20);
  20.     }
  21.     mp = NULL;
  22.     }
  23. }
  24.  
  25. static int
  26. NewFile(char *dir, int count)
  27. {
  28.     char namebuf[64];
  29.  
  30.     CloseOldFile();
  31.  
  32.     do {
  33.     sprintf(namebuf, "%s/%d", dir, ++count);
  34.     } while (access(namebuf, 0) == 0);
  35.  
  36.     if ((mp = fopen(namebuf, "w")) == NULL) {
  37.     printf("FATAL -- can't create %s to hold new message\n", namebuf);
  38.     exit(10);
  39.     }
  40.     printf("%4d: ", count);
  41.     return (count);
  42. }
  43.  
  44. static void
  45. copyline(register char *buf, FILE *fp)
  46. {
  47.     register int c;
  48.  
  49.     if (mp == NULL)
  50.     return;
  51.  
  52.     while (*buf != '\0') {
  53.     putc(*buf, mp);
  54.     if (*buf == '\n')
  55.         return;
  56.     ++buf;
  57.     }
  58.     while ((c = getc(fp)) != EOF) {
  59.     putc(c, mp);
  60.     if (c == '\n')
  61.         return;
  62.     }
  63. }
  64.  
  65. static int
  66. real_from(char *buffer, char *who)
  67. {
  68.     /*
  69.      * returns true if 's' has the seven 'from' fields,
  70.      * initializing the who to the sender
  71.      * also returns true if has dmail ARCHIVE flag
  72.      */
  73.     char fld3[20], fld7[20];
  74.  
  75.     if (strncmp(buffer, "From ", 5) != 0)
  76.     return (0);
  77.  
  78.     fld7[0] = '\0';
  79.     sscanf(buffer, "%*s %s %s %*s %*s %*s %s", who, fld3, fld7);
  80.     if (fld7[0] != '\0')
  81.     return (1);
  82.     if (strcmp(fld3, "(ARCHIVE)") != 0)
  83.     return (0);
  84.     strcpy(who, fld3);
  85.     return (1);
  86. }
  87.  
  88. static void
  89. forwarded(char *buffer, char *who)
  90. {
  91.     /*
  92.      * change 'from' and date fields to reflect the ORIGINATOR of
  93.      * the message by iteratively parsing the >From fields...
  94.      */
  95.     char machine[80], buff[80];
  96.  
  97.     machine[0] = '\0';
  98.     sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %*s %s", who, machine);
  99.  
  100.     if (machine[0] == '\0') /* try for srm address */
  101.     sscanf(buffer, "%*s %s %*s %*s %*s %*s %*s %*s %s", who, machine);
  102.  
  103.     if (machine[0] == '\0')
  104.     sprintf(buff, "anonymous");
  105.     else
  106.     sprintf(buff, "%s!%s", machine, who);
  107.  
  108.     strncpy(who, buff, 80);
  109. }
  110.  
  111. static void
  112. remove_first_word(char *dest, char *string)
  113. {
  114.     /*
  115.      * Removes first word of string, i.e., up to first non-white space
  116.      * following a white space, and copies it to the destination.
  117.      */
  118.     while (!isspace(*string))
  119.     ++string;
  120.     while (isspace(*string))
  121.     ++string;
  122.     while (*dest++ = *string++)
  123.     ;
  124.     if (dest[-2] == '\n')
  125.     dest[-2] = '\0';
  126. }
  127.  
  128. static void
  129. show_header(char *from, char *subject)
  130. {
  131.     /*
  132.      * output header in clean format, including abbreviation
  133.      * of return address if more than one machine name is
  134.      * contained within it!
  135.      */
  136.     register char *p, *q, *r;
  137.  
  138. #ifdef PREFER_UUCP
  139.     if (chloc(from, '!') != -1 && chloc(from, '@') > 0) {
  140.     for (p=from; *p != '@'; p++)
  141.         ;
  142.     *p = '\0';
  143.     }
  144. #endif
  145.  
  146.     p = from;
  147.     q = from;      /* find address portion */
  148.     while ((r = strchr(q, '!')) != NULL) {
  149.     p = q;
  150.     q = r + 1;
  151.     }
  152.  
  153.     printf("%-30s  %s\n", p, subject);
  154. }
  155.  
  156. static void
  157. parse_arpa_from(char *buffer, char *newfrom)
  158. {
  159.     /*
  160.      * Try to parse the 'From:' line given... It can be in one of
  161.      * two formats:
  162.      *        From: Dave Taylor <hpcnou!dat>
  163.      * or   From: hpcnou!dat (Dave Taylor)
  164.      * Change 'newfrom' ONLY if sucessfully parsed this entry and
  165.      * the resulting name is non-null!
  166.      */
  167.     register char *p, *q;
  168.     register int i;
  169.  
  170.     if (*(q = buffer + strlen(buffer) - 1) == '>') {
  171.         p = buffer + 6, q = p;        /* skip "From: " */
  172.         do {
  173.         ++q;
  174.         } while (*q != '\0' && *q != '<' && *q != '(');
  175.     } else if (*q == ')') {
  176.         p = q;
  177.         do {
  178.         --p;
  179.         } while ((p > buffer + 5) && *p != '(' && *p != '<');
  180.     } else
  181.     return;
  182.  
  183.     if (p >= q)
  184.     return;
  185.  
  186.     /* remove leading spaces... */
  187.     while (isspace(*++p))
  188.     ;
  189.  
  190.     /* remove trailing spaces... */
  191.     while (isspace(*--q))
  192.     ;
  193.  
  194.     /* if anything is left, let's change 'from' value! */
  195.     if (p >= q)
  196.     return;
  197.     i = p - q + 1;
  198.     strncpy(newfrom, p, i)[i] = '\0';
  199. }
  200.  
  201. static char buffer[1000];
  202. static char from_whom[512], subject[512];
  203.  
  204. int
  205. unpackmail(char *dir, int count)
  206. {
  207.     register FILE *fp;
  208.     register char *mailfile;
  209.  
  210.     if (access(mailfile = expand_path(dir, ".mailfile"), 0) != 0)
  211.     return count;
  212.     if ((fp = fopen(mailfile, "r")) == NULL)
  213.     return count;
  214.     mailfile = fgets(buffer, (int)sizeof buffer, fp);
  215.     fclose(fp);
  216.     if (mailfile == NULL)
  217.     return count;
  218.     if ((mailfile = strchr(buffer, '\n')) != NULL)
  219.     *mailfile = '\0';
  220.     if ((fp = fopen(buffer, "r")) == NULL)
  221.     return count;
  222.     mailfile = strdup(buffer);
  223.  
  224.     printf("New mail:\n");
  225.     mp = NULL;
  226.     while (fgets(buffer, (int)sizeof buffer, fp) != NULL) {
  227.     if (real_from(buffer, from_whom)) {
  228.         count = NewFile(dir, count);
  229.     } else if (from_whom[0] != '\0') {
  230.         if (strncmp(buffer, ">From ", 6) == 0) {
  231.         forwarded(buffer, from_whom);
  232.         } else if (strncmp(buffer, "Subject:", 8) == 0 || strncmp(buffer, "Re:", 3) == 0) {
  233.         if (subject[0] == '\0')
  234.             remove_first_word(subject, buffer);
  235.         } else if (strncmp(buffer, "From:", 5) == 0)
  236.         parse_arpa_from(buffer, from_whom);
  237.         else if (buffer[0] == '\n') {
  238.         show_header(from_whom, subject);
  239.         from_whom[0] = 0, subject[0] = 0;
  240.         }
  241.     }
  242.     copyline(buffer, fp);
  243.     }
  244.     fclose(fp);
  245.     CloseOldFile();
  246.  
  247. #ifndef TEST
  248.     remove(mailfile);
  249. #else
  250.     printf("remove(%s)\n", mailfile);
  251. #endif
  252.     free(mailfile);
  253.     return count;
  254. }
  255.  
  256. #ifdef TEST
  257. main(int argc, char **argv)
  258. {
  259.     printf("New value of count is %d\n", unpackmail("UUNEWS:mail.test", 9));
  260.     return 0;
  261. }
  262. #endif
  263.  
  264.